function [CurrentValues, CurrentStates, logP] = MHMMVITERBI (Dyn, TMatrix, EPara, fhandle)


%disp(fhandle(0.5,1));

% TMatrix must be square

NumStates = size(TMatrix,1);
checkTMatrix = size(TMatrix,2);
if checkTMatrix ~= NumStates
    error('stats:MHMMVITERBI:BadTransitions',...
          'TRANSITION MATRIX must be square.');
end

% TMatrix must agree with EPara

checkEPara = size(EPara,1);
if checkEPara ~= NumStates
    error('stats:MHMMVITERBI:BadTransitions',...
          'STATES VALUES must agree with TRANSISTION MATRIX.');
end

% fhandle check two inputs (Dyn, EPara)


% working in log space to avoid numerical issues

L = length(Dyn);
if L == 0
    return
end

logTMatrix = log(TMatrix);
logfhandle = @(x,y) log(fhandle(x,y));

% allocate space
CurrentStates = zeros(L,1);
CurrentValues = zeros(L,1);
pTR = zeros(NumStates,L);

% assumption is that model is in state 1 at step 0
v = -Inf(NumStates,1);
v(1,1) = 0;
vOld = v;

% loop through the model
for count = 1:L
    for state = 1:NumStates
        % for each state we calculate
        % v(state) = e(state,seq(count))* max_k(vOld(:)*tr(k,state));
        bestVal = -inf;
        bestPTR = 0;
        % use a loop to avoid lots of calls to max
        for inner = 1:NumStates 
            val = vOld(inner) + logTMatrix(inner,state);
            if val > bestVal
                bestVal = val;
                bestPTR = inner;
            end
        end
        % save the best transition information for later backtracking
        pTR(state,count) = bestPTR;
        % update v
        v(state) = logfhandle(Dyn(count),EPara(state,:)) + bestVal;
    end
    vOld = v;
end

% decide which of the final states is post probable
[logP, finalState] = max(v);

% Now back trace through the model
CurrentStates(L) = finalState;
CurrentValues(L) = EPara(finalState,1);
for count = L-1:-1:1
    CurrentStates(count) = pTR(CurrentStates(count+1),count+1);
    if CurrentStates(count) == 0
        error('stats:hmmviterbi:ZeroTransitionProbability',...
       ['A zero transition probability was encountered from state %d.\n',...
       'Please provide more data or PseudoTransition information.'],...
       CurrentStates(count+1));
    end
    CurrentValues(count) = EPara(CurrentStates(count),1);
end
